﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;
using Cleverscape.UTorrentClient.WebClient;

namespace FatController
{
    [ValueConversion(typeof(TimeSpan), typeof(string))]
    public class TimeSpanDisplayConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (targetType != typeof(string))
            {
                return null;
            }
            if (value is TimeSpan)
            {
                TimeSpan TimeSpanToConvert = (TimeSpan)value;
                if (TimeSpanToConvert == TimeSpan.MaxValue)
                {
                    return "∞";
                }
                if (TimeSpanToConvert.TotalDays > 365)
                {
                    return (String.Format("{0}y {1}w", TimeSpanToConvert.Days / 365, (TimeSpanToConvert.Days % 365) / 7));
                }
                if (TimeSpanToConvert.TotalDays >= 15)
                {
                    return (String.Format("{0}w {1}d", TimeSpanToConvert.Days / 7, TimeSpanToConvert.Days % 7));
                }
                if (TimeSpanToConvert.TotalHours >= 24)
                {
                    return (String.Format("{0}d {1}h", TimeSpanToConvert.Days, TimeSpanToConvert.Hours));
                }
                if (TimeSpanToConvert.TotalHours >= 1)
                {
                    return (String.Format("{0}h {1}m", TimeSpanToConvert.Hours, TimeSpanToConvert.Minutes));
                }
                if (TimeSpanToConvert.TotalMinutes >= 1)
                {
                    return (String.Format("{0}m {1}s", TimeSpanToConvert.Minutes, TimeSpanToConvert.Seconds));
                }
                return (String.Format("{0}s", TimeSpanToConvert.Seconds));
            }
            return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    [ValueConversion(typeof(int), typeof(string))]
    public class QueuePriorityDisplayConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (targetType != typeof(string))
            {
                return null;
            }
            if (value is int)
            {
                int QueuePriorityToConvert = (int)value;
                if (QueuePriorityToConvert == -1)
                {
                    return "*";
                }
                return QueuePriorityToConvert.ToString();
            }
            return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    [ValueConversion(typeof(long), typeof(string))]
    public class SizeBytesDisplayConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (targetType != typeof(string))
            {
                return null;
            }
            if (value is long)
            {
                long SizeToConvert = (long)value;
                return Utilities.FormatFileSize(SizeToConvert, false, "B");
            }
            return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    [ValueConversion(typeof(long), typeof(string))]
    public class SizeBytesShowZeroDisplayConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (targetType != typeof(string))
            {
                return null;
            }
            if (value is long)
            {
                long SizeToConvert = (long)value;
                return Utilities.FormatFileSize(SizeToConvert, true, "B");
            }
            return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    [ValueConversion(typeof(long), typeof(string))]
    public class SpeedBytesDisplayConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (targetType != typeof(string))
            {
                return null;
            }
            if (value is long)
            {
                long SizeToConvert = (long)value;
                return Utilities.FormatFileSize(SizeToConvert, false, "B/s");
            }
            return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public static class Utilities
    {
        public static string FormatFileSize(long SizeBytes, bool ShowZero, string Suffix)
        {
            long SizeToUse = SizeBytes;

            if (SizeToUse >= 1125899906842624)
            {
                Decimal size = Decimal.Divide(SizeToUse, 1125899906842624);
                return String.Format("{0:##.##} P{1}", size, Suffix);
            }
            if (SizeToUse >= 1099511627776)
            {
                Decimal size = Decimal.Divide(SizeToUse, 1099511627776);
                return String.Format("{0:##.##} T{1}", size, Suffix);
            }
            if (SizeToUse >= 1073741824)
            {
                Decimal size = Decimal.Divide(SizeToUse, 1073741824);
                return String.Format("{0:##.##} G{1}", size, Suffix);
            }
            else if (SizeToUse >= 1048576)
            {
                Decimal size = Decimal.Divide(SizeToUse, 1048576);
                return String.Format("{0:##.##} M{1}", size, Suffix);
            }
            else if (SizeToUse >= 1024)
            {
                Decimal size = Decimal.Divide(SizeToUse, 1024);
                return String.Format("{0:##.##} K{1}", size, Suffix);
            }
            else if (SizeToUse > 0 & SizeToUse < 1024)
            {
                Decimal size = SizeToUse;
                return String.Format("{0:##.##} {1}", size, Suffix);
            }
            else
            {
                if (ShowZero)
                {
                    return String.Format("0 {0}", Suffix);
                }
                else
                {
                    return "";
                }
            }
        }
    }

    [ValueConversion(typeof(decimal), typeof(string))]
    public class SeedPeerRatioDisplayConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (targetType != typeof(string))
            {
                return null;
            }
            if (value is decimal)
            {
                decimal RatioToConvert = (decimal)value;
                if (RatioToConvert == decimal.MaxValue)
                {
                    return "∞";
                }
                return RatioToConvert.ToString("0.000");
            }
            return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    [ValueConversion(typeof(TorrentSimpleStatus), typeof(string))]
    public class StatusDisplayConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (targetType != typeof(string))
            {
                return null;
            }
            if (value is TorrentSimpleStatus)
            {
                TorrentSimpleStatus StatusToConvert = (TorrentSimpleStatus)value;
                switch (StatusToConvert)
                {
                    case TorrentSimpleStatus.DownloadingQueued:
                        return "Queued";
                    case TorrentSimpleStatus.Downloading:
                        return "Downloading";
                    case TorrentSimpleStatus.DownloadingError:
                        return "Error Downloading";
                    case TorrentSimpleStatus.InactiveIncomplete:
                        return "Stopped";
                    case TorrentSimpleStatus.SeedingQueued:
                        return "Queued Seed";
                    case TorrentSimpleStatus.Seeding:
                        return "Seeding";
                    case TorrentSimpleStatus.SeedingError:
                        return "Error Seeding";
                    case TorrentSimpleStatus.InactiveCompleted:
                        return "Finished";
                    case TorrentSimpleStatus.Paused:
                        return "Paused";
                    case TorrentSimpleStatus.Error:
                        return "Error";
                    default:
                        break;
                }
            }
            return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    [ValueConversion(typeof(TorrentSimpleStatus), typeof(System.Windows.Media.ImageSource))]
    public class StatusImageDisplayConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (targetType != typeof(System.Windows.Media.ImageSource))
            {
                return null;
            }
            if (value is TorrentSimpleStatus)
            {
                TorrentSimpleStatus StatusToConvert = (TorrentSimpleStatus)value;
                switch (StatusToConvert)
                {
                    case TorrentSimpleStatus.DownloadingQueued:
                        return BitmapToImageSource(Properties.Resources.Status7DownloadQueued);
                    case TorrentSimpleStatus.Downloading:
                        return BitmapToImageSource(Properties.Resources.Status1Downloading);
                    case TorrentSimpleStatus.DownloadingError:
                        return BitmapToImageSource(Properties.Resources.Status5Error);
                    case TorrentSimpleStatus.InactiveIncomplete:
                        return BitmapToImageSource(Properties.Resources.Status3InactiveIncomplete);
                    case TorrentSimpleStatus.SeedingQueued:
                        return BitmapToImageSource(Properties.Resources.Status8SeedingQueued);
                    case TorrentSimpleStatus.Seeding:
                        return BitmapToImageSource(Properties.Resources.Status2Seeding);
                    case TorrentSimpleStatus.SeedingError:
                        return BitmapToImageSource(Properties.Resources.Status5Error);
                    case TorrentSimpleStatus.InactiveCompleted:
                        return BitmapToImageSource(Properties.Resources.Status6Finished);
                    case TorrentSimpleStatus.Paused:
                        return BitmapToImageSource(Properties.Resources.Status4Paused);
                    case TorrentSimpleStatus.Error:
                        return BitmapToImageSource(Properties.Resources.Status5Error);
                    default:
                        break;
                }
            }
            return null;
        }

        private System.Windows.Media.ImageSource BitmapToImageSource(System.Drawing.Bitmap InputBitmap)
        {
            return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                    InputBitmap.GetHbitmap(),
                    IntPtr.Zero,
                    System.Windows.Int32Rect.Empty,
                    System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}
